package com.kfyang.manualgear.daoplugin.generator.ui;

import com.intellij.openapi.project.Project;
import com.intellij.ui.LanguageTextField;
import com.kfyang.manualgear.daoplugin.simple.SimpleLanguage;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class YmlGenerateUI {

    private JPanel rootPanel;
    private JLabel methodNameText;
    private JComboBox<String> typeComboBox;
    private JButton addColumnButton;

    private JLabel columnLabel;
    private JPanel columnPanel;

    private JRadioButton constructorRadioButton;
    private JRadioButton resultMappingRadioButton;
    private JLabel resultLabel;
    private JPanel resultPanel;
    private JPanel sqlPanel;
    private JPanel fragPanel;
    private JButton addFragButton;
    private JButton removeColumnButton;
    private JScrollPane columnScrollPanel;
    private JButton removeFragButton;
    private JPanel constructPanel;
    private JTextField constructIdText;
    private JButton removeResultButton;
    private JButton addResultButton;
    private JScrollPane resultMappingScrollPanel;
    private JPanel resultContentPanel;
    private JPanel resultMappingPanel;
    private JScrollPane fragScrollPanel;
    private final LanguageTextField sqlTextField;

    private final java.util.List<JTextField> colList = new ArrayList<>();
    private final java.util.List<FragElement> fragList = new ArrayList<>();
    private final java.util.List<JTextField> resultMappingList = new ArrayList<>();

    {
        typeComboBox.addItem("QUERY");
        typeComboBox.addItem("MODIFY");

        typeComboBox.addActionListener(e -> {
            boolean b = "QUERY".equals(typeComboBox.getSelectedItem());
            columnLabel.setVisible(b);
            columnScrollPanel.setVisible(b);
            resultLabel.setVisible(b);
            resultPanel.setVisible(b);
            resultContentPanel.setVisible(b);
        });

        addColumnButton.addActionListener(e -> {
            int pos = colList.size();
            JTextField jTextField = new JTextField();
            jTextField.setPreferredSize(new Dimension(100, 30));
            columnPanel.add(jTextField, pos);
            if (pos == 0) {
                removeColumnButton.setEnabled(true);
            }
            colList.add(jTextField);

            columnScrollPanel.repaint();
            columnScrollPanel.validate();
        });

        removeColumnButton.addActionListener(e -> {
            int pos = colList.size() - 1;
            colList.remove(pos);
            columnPanel.remove(pos);
            if (pos == 0) {
                removeColumnButton.setEnabled(false);
            }
            columnScrollPanel.repaint();
            columnScrollPanel.validate();
        });

        addFragButton.addActionListener(e -> {
            int pos = fragList.size();
            FragElement fragElement = new FragElement();
            fragPanel.add(fragElement.getFragPanel(), pos);
            if (pos == 0) {
                removeFragButton.setEnabled(true);
            }
            if (pos == 2) {
                addFragButton.setEnabled(false);
            }
            fragList.add(fragElement);
            fragScrollPanel.repaint();
            fragScrollPanel.validate();
        });

        removeFragButton.addActionListener(e -> {
            int pos = fragList.size() - 1;
            fragList.remove(pos);
            fragPanel.remove(pos);
            if (pos == 0) {
                removeFragButton.setEnabled(false);
            }
            if (pos == 2) {
                addFragButton.setEnabled(true);
            }
            fragScrollPanel.repaint();
            fragScrollPanel.validate();
        });

        ItemListener radioListener = e -> {
            final Object source = e.getItem();
            if (!(source instanceof JRadioButton radioButton) || !radioButton.isSelected()) {
                return;
            }
            boolean b = radioButton == constructorRadioButton;
            constructPanel.setVisible(b);
            resultMappingScrollPanel.setVisible(!b);
        };
        constructorRadioButton.addItemListener(radioListener);
        resultMappingRadioButton.addItemListener(radioListener);

        constructorRadioButton.doClick();

        addResultButton.addActionListener(e -> {
            int pos = resultMappingList.size();
            JTextField jTextField = new JTextField();
            jTextField.setPreferredSize(new Dimension(100, 30));
            resultMappingPanel.add(jTextField, pos);
            if (pos == 0) {
                removeResultButton.setEnabled(true);
            }
            resultMappingList.add(jTextField);
            resultMappingScrollPanel.repaint();
            resultMappingScrollPanel.validate();
        });

        removeResultButton.addActionListener(e -> {
            int pos = resultMappingList.size() - 1;
            resultMappingList.remove(pos);
            resultMappingPanel.remove(pos);
            if (pos == 0) {
                removeResultButton.setEnabled(false);
            }

            resultMappingScrollPanel.repaint();
            resultMappingScrollPanel.validate();
        });
    }

    public YmlGenerateUI(Project project) {
        sqlTextField = new LanguageTextField(SimpleLanguage.INSTANCE, project, "", false);
        sqlTextField.setPreferredSize(new Dimension(-1, 80));
        sqlPanel.add(sqlTextField);
    }

    public JPanel getRootPanel() {
        return rootPanel;
    }

    public JLabel getMethodNameText() {
        return methodNameText;
    }

    public String getYmlText() {
        Map<String, Object> res = new LinkedHashMap<>();

        res.put("methodName", methodNameText.getText());
        String type = (String) typeComboBox.getSelectedItem();
        res.put("type", type);
        res.put("sql", sqlTextField.getText());
        if ("QUERY".equals(type)) {
            List<String> cols = colList.stream().map(JTextComponent::getText).toList();
            res.put("cols", cols);
            if (constructorRadioButton.isSelected()) {
                res.put("construct", constructIdText.getText());
            } else {
                List<String> list = resultMappingList.stream().map(JTextComponent::getText).collect(Collectors.toList());
                res.put("resultMap", list);
            }
        }

        var frags = fragList.stream().map(fragElement -> {
            Map<String, String> frag = new LinkedHashMap<>();
            frag.put("id", fragElement.getFragIdField().getText());
            frag.put("sql", fragElement.getFragSqlField().getText());
            frag.put("cond", fragElement.getFragCondField().getText());
            return frag;
        }).collect(Collectors.toList());
        res.put("frags", frags);

        DumperOptions dumperOptions = new DumperOptions();
        dumperOptions.setIndentWithIndicator(true);
        dumperOptions.setIndicatorIndent(2);
        Yaml yaml = new Yaml(dumperOptions);
        return yaml.dumpAsMap(res);
    }
}
